#include "Jeu.h"
#include "RiskFactory.h"

Jeu* Jeu::uniqueInstance= NULL;

Jeu* Jeu::getInstance() {

	if (uniqueInstance == NULL) {		
		uniqueInstance = new Jeu;
	} 
	return uniqueInstance;
}

Jeu::Jeu() {
}

Jeu::~Jeu() {
}

void Jeu::initJeu(int nombreJoueur) {

	// Recuperation de la riskfactory	
	RiskFactory* riskFactory = RiskFactory::getInstance();

	// Initialisation du monde
	leMonde = riskFactory->creerMonde();

	// Creation des joueurs
	cout << "------------------------------------" << endl;
	cout << "Bonjour et Bienvenu dans le Jeu RISK" << endl;
	cout << "------------------------------------" << endl;

	cout << "- creation des joueurs..." << endl;	

	// Joueur 1
	Joueur* joueur1 = riskFactory->creerJoueur();
	joueur1->setNom("Benjamin");
	joueur1->setRace(Joueur::ORC);	
	joueur1->setNbArmeeTotal(42);
	joueur1->setNbArmeePlace(42);
	joueur1->setNbArmeeDisponible(0);
	
	

	// Joueur 2
	Joueur* joueur2 = riskFactory->creerJoueur();
	joueur2->setNom("Youenn");
	joueur2->setRace(Joueur::HUMAIN);
	joueur2->setNbArmeeTotal(42);
	joueur2->setNbArmeePlace(42);
	joueur2->setNbArmeeDisponible(0);
	
	ajouterJoueur(joueur2);
	ajouterJoueur(joueur1);

	// Distribution des territoires
	this->distribuerTerritoire();

	for (int i=0; i<lesJoueurs.size(); i++) {
		lesJoueurs[i]->afficher();
	}
}

/**********************************************************
 * distribution des territoires aux joueurs
 **********************************************************/
void Jeu::distribuerTerritoire() {

	cout << "- distibutions des territoires..." << endl;

	vector<Continent*> lesContinents = leMonde->getContinents();
	vector<Territoire*> dejaDistribue;

	int indiceJoueur = lesJoueurs.size();

	//cout << "- nombre de joueurs = " << indiceJoueur<<endl;

	int tabJoueur[lesJoueurs.size()];

	for (int i =0; i<lesJoueurs.size(); i++) {
		tabJoueur[i] = i;
	}

	for (int k = 0; k < lesContinents.size(); k++) {
		
		Continent* continent = lesContinents[k];
		vector<Territoire*> sesTerritoires = continent->getTerritoires();

		for (int i = 0; i < sesTerritoires.size(); i++) {
			
			Territoire* territoire = sesTerritoires[i];

			//remise a niveau du tableau des joueurs
			if (indiceJoueur<=0) {

				for (int j =0; j<lesJoueurs.size(); j++)
					tabJoueur[j] = j;

				indiceJoueur = lesJoueurs.size();
			}

			int randTerritoire = selectionJoueur(tabJoueur, lesJoueurs.size());
			
			Joueur* joueur = lesJoueurs[randTerritoire];
			
			tabJoueur[randTerritoire]=-1;
			joueur->ajouterTerritoire(territoire);
			territoire->setProprietaire(joueur);
			
			// Affectation de la couleur courante du territoire
			territoire->setCouleurOrigine(joueur->couleur);					
			indiceJoueur--;
		}
	}
}

/**********************************************************
 * fonction qui renvoi parmi la liste de territoires voisins
 * ceux qui appartiennent au joueur
 **********************************************************/
int Jeu::selectionJoueur(int tab[], int taille) {

	srand(time(NULL));
	int i = rand() % taille;
	while (tab[i] == -1)
		i = rand() % taille;
	return tab[i];
}

void Jeu::ajouterJoueur(Joueur* j) {
	lesJoueurs.push_back(j);
}

vector<Joueur*> Jeu::getJoueurs() const {
	return lesJoueurs;
}

Monde* Jeu::getMonde() const {
	return leMonde;
}

bool Jeu::existFrontiere(Territoire* t1, Territoire* t2) {
	
	vector<Frontiere* > lesFrontieres = this->getMonde()->getFrontieres();
	
	for(int i=0;i< lesFrontieres.size();i++) {
		
		Frontiere* frontiere = lesFrontieres[i];
		
		Territoire* ter1 = frontiere->getPays1();
		Territoire* ter2 = frontiere->getPays2();
		
		if (ter1->getNom() == t1->getNom() && ter2->getNom() == t2->getNom())
			return true;
		if (ter1->getNom() == t2->getNom() && ter2->getNom() == t1->getNom())
			return true;				
	}
	return false;	
}

Territoire* Jeu::getTerritoireById(int id) {
	
	vector<Territoire*> lesTerritoires = leMonde->getTerritoires();
	
	for (int i=0; i< lesTerritoires.size();i++) {
		
		Territoire* territoire = lesTerritoires[i];
		
		if (territoire->getId() == id) 
			return territoire;
	}
	return NULL;
}

Joueur* Jeu::getJoueurSuivant(Joueur* joueurEnCours){
	
	for (int i = 0 ; i < lesJoueurs.size(); i++) {
		
		Joueur* joueur = lesJoueurs[i];
		
		if (joueur->getNom() != joueurEnCours->getNom()){
			return joueur;
		}
		
	}
	return NULL;
}

Continent* Jeu::getContinentByTerritoire(Territoire* unTerritoire) {	
	
	vector<Continent*> lesContinents = leMonde->getContinents();
	
	for (int i = 0 ; i< lesContinents.size();i++) {		
		
		Continent* continent = lesContinents[i];
		
		//cout << continent->getNom() <<endl;
			
		vector<Territoire*> sesTerritoires = continent->getTerritoires();
		
		for (int j = 0 ; j < sesTerritoires.size(); j++) {
								
			Territoire* territoire = sesTerritoires[j];						
			
			if (territoire->getId() == unTerritoire->getId()) {
				return continent;
			}
		}
	}
	return NULL;
}


